package com.atlin.model;

import com.atlin.exception.CustomException;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.io.Serial;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 客户端信息参数模型
 */
@Data
public class ServerInfoModel implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * IP地址
     */
    private List<String> ipAddress;

    /**
     * MAC地址
     */
    private List<String> macAddress;

    /**
     * CPU序列号
     */
    private String cpuSerial;

    /**
     * 主板序列号
     */
    private String mainBoardSerial;


    /**
     * 生成唯一机器码（SHA-256 哈希）
     */
    public String generateMachineCode() {
        try {
            valid();
            // 归一化数据（排序 + 去重 + 拼接）
            String normalized = normalizeValues();

            // 计算哈希（SHA-256）
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(normalized.getBytes(StandardCharsets.UTF_8));

            // 转为可读字符串（十六进制）
            return bytesToHex(hash).toUpperCase(Locale.ROOT);

        } catch (Exception e) {
            throw new CustomException("生成机器码失败", e);
        }
    }

    /**
     * 拼接字段为规范字符串
     */
    private String normalizeValues() {
        String ip = joinAndSort(ipAddress);
        String mac = joinAndSort(macAddress);
        String cpu = safe(cpuSerial);
        String board = safe(mainBoardSerial);

        return String.join("|", ip, mac, cpu, board);
    }

    private String joinAndSort(List<String> values) {
        return values.stream()
                .filter(Objects::nonNull)
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .sorted()
                .collect(Collectors.joining(","));
    }

    private String safe(String value) {
        return value == null ? "" : value.trim();
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    /**
     * 空项校验
     */
    public void valid() {
        if (ipAddress == null || ipAddress.isEmpty() || macAddress == null || macAddress.isEmpty() || StringUtils.isAnyBlank(cpuSerial, mainBoardSerial)) {
            throw new CustomException("服务器指纹信息数据存在空项");
        }
    }
}
